import { ObjectId } from 'mongodb'
import * as db from '../db'
import { stats } from '../stats'
import { IBooks, Relevance } from '../types'
import {
  addSome,
  changenum,
  removeSome,
  checkSome,
  dealAllmid
} from './tools'

function dealPrice(value: IBooks) {
  const { books } = value
  let lowprice = 10000
  let allstock = 0
  books.forEach(item => {
    if (item.price < lowprice) lowprice = item.price
    allstock += item.stock
  })
  return { lowprice, allstock }
}

// 送书审核
export async function issuebook(id: ObjectId, value: IBooks) {
  const { lowprice, allstock } = dealPrice(value)
  const book = await db.booksCollection.insertOne({
    _id: null,
    ...value,
    publisher: id,
    createAt: Date.now(),
    updateAt: Date.now(),
    isDelete: false,
    putaway: false,
    views: 0,
    lowprice,
    allstock
  })
  await db.connectCollection.insertOne({
    _id: null,
    userId: id,
    destId: book.insertedId,
    time: Date.now(),
    type: Relevance.Myissue
  })
}

// 修改书籍信息
export async function updatebook(bookId: string, value: IBooks) {
  const { lowprice, allstock } = dealPrice(value)

  const updateRes = await db.booksCollection.findOneAndUpdate(
    { _id: new ObjectId(bookId) },
    {
      $set: {
        updateAt: Date.now(),
        ...value,
        lowprice,
        allstock,
        bookId: undefined,
        judger: null // 重新去审核
      }
    }
  )
  return updateRes.value
}

export async function delbook(bookId: string, userId: ObjectId) {
  const other = new ObjectId(bookId)
  const res = await checkSome(userId, other, Relevance.Myissue)
  if (res) {
    const delRes = await db.booksCollection.findOneAndUpdate(
      { _id: other },
      { $set: { isDelete: true } }
    )
    // 删除购物车中的树
    await db.connectCollection.deleteMany({
      destId: other,
      type: Relevance.Mycars
    })
    return delRes.value
  }
}

// 书籍信息
export async function bookinfo(bookId: string, userId?: ObjectId) {
  const bookid = new ObjectId(bookId)
  const books = await db.booksCollection
    .aggregate([
      { $match: { _id: bookid, isDelete: false } },
      {
        $lookup: {
          from: 'user',
          localField: 'publisher',
          foreignField: '_id',
          as: 'user'
        }
      },
      { $unwind: '$user' },
      {
        $project: {
          banner: 1,
          content: 1,
          major: 1,
          title: 1,
          updateAt: 1,
          views: 1,
          books: 1,
          judger: 1,
          putaway: 1,
          user: {
            _id: 1,
            avatar: 1,
            nickname: 1,
            qqnumber: 1,
            signature: 1,
            role: 1
          }
        }
      }
    ])
    .toArray()
  await changenum(bookId, { $inc: { views: 1 } })

  if (userId) {
    const res = await Promise.all([
      checkSome(userId, bookid, Relevance.Collect),
      checkSome(userId, bookid, Relevance.Mythumb),
      db.connectCollection.find({ userId, type: Relevance.Mycars }).count()
    ])
    const user = await db.userCollection.findOne(
      { _id: userId },
      { projection: { avatar: 1 } }
    )
    const [colState, like, carnum] = [!!res[0], !!res[1], res[2]]
    const obj = { colState, like, carnum, logAvatar: user.avatar }
    return { ...books[0], ...obj }
  }
  return { ...books[0] }
}

// 添加移除收藏和点赞
export async function dealBook(value: any, userId: ObjectId) {
  const { bookId, type, flag } = value
  const other = new ObjectId(bookId)
  const res = await checkSome(userId, other, type)
  const text = type === Relevance.Collect ? '收藏' : '点赞'
  if (flag) {
    if (res) return `已${text}`
    await addSome(userId, other, type)
    return `${text}成功`
  } else {
    await removeSome(userId, other, type)
    return `已取消${text}`
  }
}

// 加入删除购物车
export async function dealCar(value: any, userId: ObjectId) {
  const { bookId, flag, indexs } = value
  const total = await db.connectCollection
    .find({ userId, type: Relevance.Mycars })
    .count()

  const other = new ObjectId(bookId)
  if (!flag) {
    await db.connectCollection.deleteOne({ _id: other })
    return '已移除出购物车'
  }

  // 禁止添加自己的书
  const book = await db.booksCollection.findOne({ _id: other })
  if (book.publisher.equals(userId)) throw stats.ERR_FIRBID_CAR

  // 查询总价
  let allprice = 0
  const names: string[] = []
  const prices: number[] = []

  book.books.forEach((item, idx) => {
    if (indexs.includes(idx)) {
      allprice += item.price
      names.push(item.bookname)
      prices.push(item.price)
    }
  })

  if (total >= 10) return '购物车已经满了'
  await db.connectCollection.insertOne({
    _id: null,
    userId,
    destId: other,
    time: Date.now(),
    type: Relevance.Mycars,
    allprice,
    names,
    prices,
    indexs
  })
  return '加入购物车成功'
}

// 购物车列表 ,就给你十个购物车地方
export async function carlist(userId: ObjectId) {
  const list = await db.connectCollection
    .aggregate([
      { $match: { userId, type: Relevance.Mycars } },
      {
        $lookup: {
          from: 'books',
          localField: 'destId',
          foreignField: '_id',
          as: 'book'
        }
      },
      { $unwind: '$book' },
      {
        $project: {
          allprice: 1,
          names: 1,
          book: {
            _id: 1,
            title: 1,
            banner: 1
          }
        }
      }
    ])
    .toArray()
  const total = await db.connectCollection
    .find({ userId, type: Relevance.Mycars })
    .count()
  return { list, total }
}

// 获得书籍列表 主页
export async function blist(value: { skip: number; limit: number }) {
  const list = await db.booksCollection
    .aggregate([
      { $match: { isDelete: false, putaway: true } },
      {
        $lookup: {
          from: 'user',
          localField: 'publisher',
          foreignField: '_id',
          as: 'user'
        }
      },
      { $skip: value.skip },
      { $limit: value.limit },
      { $unwind: '$user' },
      {
        $project: {
          title: 1,
          banner: 1,
          lowprice: 1,
          allstock: 1,
          user: {
            nickname: 1,
            avatar: 1
          }
        }
      }
    ])
    .toArray()
  const total = await db.booksCollection
    .find({ isDelete: false, putaway: true })
    .count()
  return { list, total }
}

// 收藏 商品 等列表
export async function personlist(value: any) {
  const { destId, type, skip, limit } = value

  const { destIds } = await dealAllmid(new ObjectId(destId), type)

  if (type === Relevance.Maichu) {
    const total = await db.connectCollection
      .find({ _id: { $in: destIds } })
      .count()
    const list = await db.connectCollection
      .aggregate([
        { $match: { _id: { $in: destIds } } },
        {
          $lookup: {
            from: 'books',
            localField: 'destId',
            foreignField: '_id',
            as: 'book'
          }
        },
        { $unwind: '$book' },
        { $sort: { time: -1 } },
        { $skip: skip },
        { $limit: limit },
        {
          $project: {
            time: 1,
            names: 1,
            allprice: 1,
            book: { _id: 1, title: 1, banner: 1 }
          }
        }
      ])
      .toArray()
    return { list, total }
  } else {
    const total = await db.booksCollection
      .find({ _id: { $in: destIds }, isDelete: false })
      .count()

    const list = await db.booksCollection
      .aggregate([
        { $match: { _id: { $in: destIds }, isDelete: false } },
        { $sort: { updateAt: -1 } },
        { $skip: skip },
        { $limit: limit },
        {
          $project: {
            title: 1,
            banner: 1,
            lowprice: 1,
            content: 1,
            putaway: 1,
            judger: 1
          }
        }
      ])
      .toArray()
    return { list, total }
  }
}

// 获得书籍列表 搜索页  (兼顾筛选功能)
export async function searchlist(value: any) {
  const { major, text, tag, filterTime, skip, limit } = value

  const sort = filterTime ? { updateAt: -1 } : { views: -1 }
  const filterMajor = major ? { major: { $in: major } } : undefined
  const filterText = text
    ? {
        $or: [
          { title: { $regex: text } },
          { content: { $regex: text } },
          { books: { $elemMatch: { bookname: { $regex: text } } } }
        ]
      }
    : undefined
  const filterTag = tag ? { tag: { $eq: tag } } : undefined

  const list = await db.booksCollection
    .aggregate([
      {
        $match: {
          ...filterMajor,
          ...filterText,
          isDelete: false,
          putaway: true
        }
      },
      { $sort: sort },
      { $skip: skip },
      { $limit: limit },
      {
        $project: {
          title: 1,
          banner: 1,
          lowprice: 1,
          content: 1,
          major: 1
        }
      }
    ])
    .toArray()
  const total = await db.booksCollection
    .find({ ...filterMajor, ...filterText, isDelete: false, putaway: true })
    .count()
  return { list, total }
}
